home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
knowhow4
/
write.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-10
|
21KB
|
759 lines
#include "write.h"
#include "ask_hot.h"
#include "ask_str.h"
void settext()
{
settextstyle(DEFAULT_FONT, HORIZ_DIR, 1);
settextjustify(LEFT_TEXT, TOP_TEXT);
setcolor(pColorSet->colors.ATTR_COLOR);
}
////////////////////////
Write::Write(rect coordinates, char* swapName, char* fName, char* h,
int s, BORDERS b_type, BORDERS hdr_b_type, int pat, int hdr_pat)
: Window(coordinates, fName, h, s, b_type, hdr_b_type, FIXED, pat,
hdr_pat)
{
clip = NULL;
mark = 0;
mark_begin = mark_end = -1;
status = INS | SAVED;
swapFile = swapName == NULL ? NULL : strdup(swapName);
buffer = NULL;
line_num = 0;
curs = loc(0, 0);
xTab = 0;
total = 0;
}
///////////////////////////////// // ATTENTION !!!
Write::~Write() // The Write is a very simple editor,
{ // Which could be used as POPUP
delete swapFile; // window object only. The ~Write
swapFile = NULL;
delete clip;
} // does not delete buffer - we suppose
///////////////////////////////// // that you first call hide() function.
void Write::load_file()
{
FILE* file;
if((file = fopen(swapFile, "rb")) == NULL)
file = fopen(swapFile, "wb");
delete buffer;
buffer = (char**)malloc(STRINGS * sizeof(char*)); // N lines only
for(int i = 0; i < STRINGS; i++) // Allocate 100 strings
buffer[i] = new char[STRING_LEN];
for(total = 0; total < STRINGS; total++)
{
if(fgets(buffer[total], STRING_LEN, file) == NULL)
break;
char* string;
if((string = strchr(buffer[total], '\n')) == NULL)
buffer[total][STRING_LEN - 1] = '\r';
else
{
buffer[total][string - buffer[total]] = '\0';
buffer[total][string - buffer[total] - 1] = '\r';
}
}
buffer[total][0] = '\r';
buffer[total][1] = '\0';
fclose(file);
}
////////////////////////////////
void Write::unload_file()
{
if(!(status & SAVED) && ask_save())
swap();
for(int i = 0; i < STRINGS; i++)
delete buffer[i];
delete buffer;
buffer = NULL;
}
////////////////////////////////
void Write::show()
{
Window::show();
load_file();
line_num = 0;
curs = loc(0, 0);
xTab = 0;
show_text(loc(0, 0));
showCursor();
}
////////////////////////
void Write::hide()
{
unload_file();
Window::hide();
}
////////////////////////
void Write::show_text(loc from)
{
loc res = curs;
settext();
rect r = user_screen();
bar(rect(r.origin.X, r.origin.Y + curs.Y, r.corner.X, r.corner.Y),
(int)pColorSet->colors.BAK_COLOR,
(int)pColorSet->colors.ATTR_COLOR, (uchar*)::pattern[pattern]);
setviewport(r.origin.X, r.origin.Y, r.corner.X, r.corner.Y, 1);
while(curs.Y < user_screen().height() && from.Y <= total)
{
if(from.X <= strlen(buffer[from.Y]))
{
if(from.Y >= mark_begin && from.Y <= mark_end)
{
bar(rect(0, curs.Y,
r.width(), curs.Y + (int)pScreenSet->sub_interval),
(int)pColorSet->colors.MARK_BAK_COLOR,
(int)pColorSet->colors.MARK_COLOR,
(uchar*)::pattern[pattern]);
setcolor((int)pColorSet->colors.MARK_COLOR);
}
else
setcolor((int)pColorSet->colors.ATTR_COLOR);
outtextxy(curs.X, curs.Y, buffer[from.Y] + from.X);
}
from.Y++;
curs.Y += pScreenSet->sub_interval;
curs.X = 0;
moveto(curs);
}
setviewport(0, 0, getmaxx(), getmaxy(), 1);
curs = res;
}
//////////////////////////////
void Write::outtext(int x, int y, char* txt)
{
settext();
rect r = user_screen();
setviewport(r.origin.X, r.origin.Y, r.corner.X, r.corner.Y, 1);
int right =
curs.X + textwidth(txt) > r.width() - pScreenSet->standart_width
? r.width() : curs.X + textwidth(txt)
+ pScreenSet->standart_width;
rect r1(curs.X, curs.Y, right,
curs.Y + pScreenSet->sub_interval - 1);
if(line_num >= mark_begin && line_num <= mark_end)
{
setcolor((int)pColorSet->colors.MARK_COLOR);
bar(r1, (int)pColorSet->colors.MARK_BAK_COLOR,
(int)pColorSet->colors.MARK_COLOR, (uchar*)::pattern[pattern]);
}
else
{
setcolor((int)pColorSet->colors.ATTR_COLOR);
bar(r1, (int)pColorSet->colors.BAK_COLOR,
(int)pColorSet->colors.FILL_COLOR, (uchar*)::pattern[pattern]);
}
outtextxy(x, y, txt);
setviewport(0, 0, getmaxx(), getmaxy(), 1);
}
//////////////////////////////
void Write::swap()
{
FILE* file;
if((file = fopen(swapFile, "wb")) == NULL)
return;
for(int i = 0; i <= total; i++)
{
fputs(buffer[i], file);
fputc('\n', file);
}
fclose(file);
status = (status & INS) | SAVED;
}
//////////////////////////////
void Write::exe(int act)
{
e.what = act ? KEYEVENT : NOEVENT;
switch(act)
{
case AC_LEFT: e.key = EVENT_LEFT; break;
case AC_RIGHT: e.key = EVENT_RIGHT; break;
case AC_UP: e.key = EVENT_UP; break;
case AC_DOWN: e.key = EVENT_DN; break;
case AC_PG_UP: e.key = EVENT_PG_UP; break;
case AC_PG_DN: e.key = EVENT_PG_DN; break;
case AC_CTRL_PG_UP: e.key = EVENT_CTRL_PG_UP; break;
case AC_CTRL_PG_DN: e.key = EVENT_CTRL_PG_DN; break;
case AC_CANCEL: e.key = EVENT_ESC; break;
case AC_OK: e.key = EVENT_F2; break;
}
mouseHideCursor();
hilite();
int on = 0;
mouseShowCursor();
while(1)
{
mouseShowCursor();
if(!act && !(e.what == MOUSEEVENT && !on))
get_event();
else
on = 1;
mouseHideCursor();
if(e.what == KEYEVENT)
switch(e.key)
{
case EVENT_F1: global_i[0] = action_type;
return;
case EVENT_RIGHT: right(1); break;
case EVENT_LEFT: left(1); break;
case EVENT_UP: up(1); break;
case EVENT_DN: dn(1); break;
case EVENT_HOME: home(); break;
case EVENT_END: end(); break;
case EVENT_PG_UP: pgUp(); break;
case EVENT_PG_DN: pgDn(); break;
case EVENT_CTRL_PG_UP: toTop(); break;
case EVENT_CTRL_PG_DN: toBottom(); break;
case EVENT_ESC:
case EVENT_F6:
case EVENT_F10:
// case EVENT_TAB:
case EVENT_ALT_TAB:
case EVENT_ALT_F4:
global_num = 1; global_i[0] = 0;
return;
case EVENT_F2: swap(); unhilite(); global_num = 1;
global_i[0] = action_type; return;
case EVENT_DEL: status = (status & INS);
del(); break;
case EVENT_INS:
status = (status & INS);
setInsert();
break;
case EVENT_BKSP: status = (status & INS);
bksp(); break;
case EVENT_CTRL_Y:
ctrl_y(); status = (status & INS); break;
case EVENT_RETURN:
processKey('\n'); status = (status & INS); break;
case EVENT_SHIFT_F6: // Begin / end mark
if(mark)
mark_end = line_num;
else
mark_begin = line_num;
mark = !mark;
hideCursor();
int res = curs.Y;
curs.Y = 0;
show_text(loc(xTab, 0));
curs.Y = res;
showCursor();
break;
case EVENT_SHIFT_F2:
copy();
break;
case EVENT_SHIFT_F3:
cut();
break;
case EVENT_SHIFT_F4:
paste();
break;
/* case EVENT_ALT_F7: // Unremark if you want
if(!ask_str(rectangle)) // to get more trouble.
break;
hideCursor();
search();
Border::show();
showCursor();
break;
case EVENT_F7:
hideCursor();
search();
Border::show();
showCursor();
break;
*/ default:
if(e.is_char())
{
status = (status & INS);
processKey(e.key);
}
break;
}
else
{
if(!mouse_in(e.where())) // outside of edit window
{
unhilite();
global_num = 0; global_i[0] = AC_NULL;
return;
}
}
if(act) // leave menu and return to the object which calls it
{ // after single processing of "act" command
return;
}
}
}
///////////////////////////////
void Write::search()
{
mark = 0;
for(int i = line_num; i < total; i++)
{
char* s;
if((s = strstr(buffer[i] + xTab + textX(curs.X), global[0])) != NULL)
{
xTab = s - buffer[i];
rect r = user_screen();
curs = loc(0, 0);
line_num = i;
show_text(loc(xTab, line_num));
break;
}
}
}
///////////////////////////////
void Write::showCursor()
{
rect r = user_screen();
setviewport(r.origin.X, r.origin.Y, r.corner.X, r.corner.Y, 1);
setwritemode(XOR_PUT);
setlinestyle(SOLID_LINE, 1, 3);
moveto(curs);
lineto(curs.X, curs.Y + pScreenSet->standart_height);
setwritemode(COPY_PUT);
setviewport(0, 0, getmaxx(), getmaxy(), 1);
}
//////////////////////////////
int Write::copy()
{
if(mark_begin == -1)
return 0;
delete clip;
clip = new KH_STRTABLE(0);
for(int i = mark_begin; i <= mark_end; i++)
{
clip->add(buffer[i]);
}
return 1;
}
////////////////
void Write::cut()
{
if(!copy())
return;
for(int i = mark_begin, j = mark_end; i < mark_end && i < total; i++, j++)
buffer[i] = buffer[j];
total -= mark_end - mark_begin;
}
////////////
void Write::paste()
{
if(clip == NULL)
return;
hideCursor();
for(int i = total; i >= line_num; i--)
strcpy(buffer[i + clip->used], buffer[i]);
for(int j = 0, k = line_num; j < clip->used; j++, k++)
strcpy(buffer[k], clip->strings[j]);
total += clip->used;
rect r = user_screen();
show_text(loc(xTab, line_num));
showCursor();
}
////////////
void Write::up(int sh)
{
hideCursor();
rect r = user_screen();
if(curs.Y >= sh * pScreenSet->sub_interval)
{
curs.Y -= sh * pScreenSet->sub_interval;
line_num -= sh;
}
else
{
if(line_num < sh)
{
showCursor();
return;
}
line_num -= sh;
curs = loc(0, 0);
if(line_num < r.height() / pScreenSet->sub_interval)
{
show_text(loc(xTab, 0));
curs.Y = line_num * pScreenSet->sub_interval;
}
else
{
show_text(loc(xTab,
line_num - (r.height() / pScreenSet->sub_interval) + 1));
curs.Y = (r.height() / pScreenSet->sub_interval - 1)
* (pScreenSet->sub_interval);
}
}
showCursor();
}
/////////////////////////////
void Write::dn(int sh)
{
if(line_num + sh >= total)
return;
hideCursor();
rect r = user_screen();
if(curs.Y < r.height() - (sh + 1) * pScreenSet->sub_interval)
{
curs.Y += sh * pScreenSet->sub_interval;
line_num += sh;
}
else
{
curs = loc(0, 0);
line_num += sh;
show_text(loc(xTab, line_num));
}
showCursor();
}
/////////////////////////////////
void Write::left(int sh)
{
hideCursor();
if(curs.X >= sh * pScreenSet->standart_width)
curs.X -= sh * pScreenSet->standart_width;
else if(xTab >= sh - textX(curs.X))
{
xTab -= (sh - textX(curs.X));
rect r = user_screen();
int res = curs.Y;
curs.X = 0;
curs.Y = 0;
show_text(loc(xTab,
line_num / (r.height() / pScreenSet->sub_interval)
* (r.height() / pScreenSet->sub_interval)));
curs.Y = res;
}
showCursor();
}
////////////////////////////////
void Write::right(int sh)
{
hideCursor();
rect r = user_screen();
int len = strlen(buffer[line_num]);
int pos = textX(curs.X) + xTab;
if(curs.X < r.width() - sh * pScreenSet->standart_width
&& pos < len - sh)
curs.X += sh * pScreenSet->standart_width;
else if(pos < len - sh)
{
xTab += sh;
int res = curs.Y;
curs.Y = 0;
show_text(loc(xTab,
line_num / (r.height() / pScreenSet->sub_interval)
* (r.height() / pScreenSet->sub_interval)));
curs.Y = res;
}
showCursor();
}
////////////////////////////////
void Write::home()
{
int sh = xTab + textX(curs.X);
left(sh);
}
////////////////////////////////
void Write::end()
{
int sh = strlen(buffer[line_num]) - (xTab + textX(curs.X)) - 1;
right(sh);
}
///////////////////////////////
void Write::pgUp()
{
int sh = user_screen().height() / pScreenSet->sub_interval;
up(sh);
}
///////////////////////////////
void Write::pgDn()
{
int sh = user_screen().height() / pScreenSet->sub_interval;
dn(sh);
}
///////////////////////////////
void Write::toTop()
{
int sh = line_num;
up(sh);
}
//////////////////////////////
void Write::toBottom()
{
int sh = total - line_num - 1;
dn(sh);
}
//////////////////////////////
void Write::ctrl_y()
{
mark = 0;
hideCursor();
char* tmp = buffer[line_num];
for(int i = line_num; i < total; i++)
buffer[i] = buffer[i + 1];
buffer[total] = tmp;
total--;
curs.X = 0;
if(xTab)
{
rect r = user_screen();
xTab = 0;
show_text(loc(0,
line_num / (r.height() / pScreenSet->sub_interval)
* (r.height() / pScreenSet->sub_interval)));
}
else
show_text(loc(0, line_num));
if(line_num >= mark_begin && line_num <= mark_end)
mark_end--;
showCursor();
}
/////////////////////////////
int Write::append(int line)
{
if(strlen(buffer[line]) + strlen(buffer[line + 1])
> STRING_LEN)
return 0;
strcpy(buffer[line] + strlen(buffer[line] + 1),
buffer[line + 1]);
char* tmp = buffer[line + 1];
for(int i = line + 1; i < total; i++)
buffer[i] = buffer[i + 1];
buffer[total] = tmp;
total--;
return 1;
}
/////////////////////////////
void Write::del()
{
mark = 0;
if(xTab + textX(curs.X) >= strlen(buffer[line_num]))
end();
int pos = xTab + textX(curs.X);
hideCursor();
if(pos == strlen(buffer[line_num] + 1))
{
if(line_num < total)
{
if(!append(line_num))
{
showCursor();
return;
}
int res = curs.X;
curs.X = 0;
if(line_num >= mark_begin && line_num <= mark_end)
mark_end--;
show_text(loc(xTab, line_num));
curs.X = res;
}
}
else
{
for(int i = pos; i < strlen(buffer[line_num]); i++)
buffer[line_num][i] = buffer[line_num][i + 1];
outtext(curs.X, curs.Y, buffer[line_num] + pos);
}
showCursor();
}
/////////////////////////////
void Write::bksp()
{
mark = 0;
hideCursor();
rect r = user_screen();
if(xTab == 0 && curs.X == 0)
{
int width = strlen(buffer[line_num - 1] + 1);
if(line_num > 0)
if(!append(line_num - 1))
{
showCursor();
return;
}
line_num--;
if(line_num >= mark_begin && line_num <= mark_end)
mark_end--;
if(screenXL(width) > r.width())
xTab = width - textX(r.width());
else
curs.X = screenXL(width);
if(curs.Y > 0)
curs.Y -= pScreenSet->sub_interval;
int res = curs.X;
curs.X = 0;
show_text(loc(xTab, line_num));
curs.X = res;
showCursor();
return;
}
if(xTab + textX(curs.X) >= strlen(buffer[line_num]))
{
showCursor();
end();
hideCursor();
}
if(xTab != 0 && curs.X == 0)
{
xTab--;
for(int i = xTab; i < strlen(buffer[line_num]); i++)
buffer[line_num][i] = buffer[line_num][i + 1];
show_text(loc(xTab, line_num));
}
else
{
curs.X -= pScreenSet->standart_width;
int pos = textX(curs.X) + xTab;
for(int i = pos; i < strlen(buffer[line_num]); i++)
buffer[line_num][i] = buffer[line_num][i + 1];
outtext(curs.X, curs.Y, buffer[line_num] + pos);
}
showCursor();
}
/////////////////////////////
void Write::processKey(uchar ch)
{
mark = 0;
rect r = user_screen();
if(xTab + textX(curs.X) >= strlen(buffer[line_num]))
end();
hideCursor();
if(ch == '\n')
{
if(total >= STRINGS - 1) // 99 == 100 - 1
{
showCursor();
return;
}
char* tmp = buffer[total + 1];
for(int i = total + 1; i > line_num + 1; i--)
buffer[i] = buffer[i - 1];
buffer[line_num + 1] = tmp;
strcpy(buffer[line_num + 1], buffer[line_num] + xTab
+ textX(curs.X));
int len1 = xTab + textX(curs.X) + 1;
buffer[line_num][len1 - 1] = '\r';
buffer[line_num][len1] = '\0';
curs.X = 0;
int res = curs.Y;
if(xTab || curs.Y + pScreenSet->sub_interval > r.height())
{
curs.Y = 0;
if(line_num >= mark_begin && line_num <= mark_end)
mark_end++;
show_text(loc(0,
line_num / (r.height() / pScreenSet->sub_interval)
* (r.height() / pScreenSet->sub_interval)));
}
else
{
if(line_num >= mark_begin && line_num <= mark_end)
mark_end++;
show_text(loc(0, line_num));
}
xTab = 0;
line_num++;
total++;
curs.Y = res + pScreenSet->sub_interval > r.height()
? res : res + pScreenSet->sub_interval;
}
else
{
if(strlen(buffer[line_num]) >= STRING_LEN - 1)
{
showCursor();
return;
}
for(int i = strlen(buffer[line_num]);
i >= xTab + textX(curs.X); i--)
buffer[line_num][i + 1] = buffer[line_num][i];
buffer[line_num][i + 1] = ch;
if(curs.X + pScreenSet->standart_width < r.width())
{
outtext(curs.X, curs.Y, buffer[line_num] + xTab
+ textX(curs.X));
curs.X += pScreenSet->standart_width;
}
else
{
xTab += textX(r.width()) + 1;
int res = curs.Y;
curs = loc(0, 0);
show_text(loc(xTab,
line_num / (r.height() / pScreenSet->sub_interval)
* (r.height() / pScreenSet->sub_interval)));
curs.Y = res;
}
}
showCursor();
}
/////////////////////////////
void Write::repose(rect new_coord)
{
Window::repose(new_coord);
}
///////////////////////////
/*
void main()
{
if(!init_KNOW_HOW())
return;
setfillstyle(SOLID_FILL, pColorSet->colors.BAK_COLOR);
bar(0, 0, getmaxx(), getmaxy());
Write s(rect(10, 0, 60, 24), "work.txt", "window.pcy", "EDITOR",
8, SHOW_BORDER, SHOW_BORDER, 0, 0);
s.set_mark(2, 3);
s.show_window();
s.hide();
s.repose(rect(0, 0, 40, 20));
s.show_window();
s.exe();
s.hide();
close_KNOW_HOW();
closegraph();
}
*/